package java44th.group.controller.admin.auth;

import java44th.group.bean.admin.AdminInfoBean;
import java44th.group.bean.admin.InfoData;
import java44th.group.bean.admin.LoginUserData;
import java44th.group.bean.admin.bo.auth.LoginBo;
import java44th.group.bean.common.BasePageInfo;
import java44th.group.bean.po.MarketAdmin;
import java44th.group.bean.admin.vo.BaseRespVo;
import java44th.group.bean.admin.vo.auth.AdminInfoEntity;
import java44th.group.bean.admin.vo.auth.LoginVo;
import java44th.group.config.realm.MarketToken;
import java44th.group.service.admin.auth.AuthService;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName project-second
 * @Descriptiom 还没写好，不用理这个类兄弟们
 * @Aurhor: 蔡文强
 * @Since: 2022/10/11 21:41
 */
@RestController
@RequestMapping("admin/auth")
public class AuthController2 {


    @Autowired
    AuthService authService;

    @RequestMapping("noAuthc")
    public BaseRespVo noAuthc() {
        return BaseRespVo.error(502, "还未认证");
    }

    @RequestMapping("logout")
    public BaseRespVo logout() {
        return BaseRespVo.ok(null);
    }


    /**
     * Shiro安全框架 → 视频课程 4个课时 → 认证（登录）
     * 如果参数比较少，类型比较简单的话，使用map来接收也可以
     */

    // 这个接口一定要设置成匿名的拦截器"anon"，不然进都进不来
    @PostMapping("login")
    public BaseRespVo login(@RequestBody Map map) {
        String username = (String) map.get("username");
        String password = (String) map.get("password");

        // 在这里要执行登录，Subject.login （我们可以很方便的获得到Subject）
        // Subject相对来说是线程安全的
        // ->Subject只能作为局部变量，不能作为全局变量。
        // 因为每个用户不应该共享同一个Subject
        // 即不同用户用的是不同的Subject，同个用户用的是相同的subject（Shiro帮我们维护了这个事情）

        // 注意这个要在方法里使用，不要作为全局变量来使用！否则应用程序一定会报异常、报错的
        Subject subject = SecurityUtils.getSubject();
        // 执行登录（认证）
        UsernamePasswordToken authenticationToken = new MarketToken(username, password, "admin");
        // 登录里面需要AuthenticationToken 令牌，其实这个是个接口 所以我们需要它的子实现类UsernamePasswordToken，如上
        try {
            subject.login(authenticationToken);
        } catch (Exception e) {
            // 这个登录方法通常是需要try-catch!!!
            // 如果没有异常说明登录成功（正常）
            e.printStackTrace();
        }

        // 判断是否认证成功
        // 根据返回的值来决定是否放行
        // 如果认证成功会返回true
        boolean authenticated = subject.isAuthenticated();
        // 可以获得Session信息，从而获得SessionId信息
        Session session = subject.getSession();

        // 获得Principal信息 → realm的doGetAuthorizationInfo方法构造的认证信息的第一个参数
        MarketAdmin primaryPrincipal = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();


        LoginUserData loginUserData = new LoginUserData();
        AdminInfoBean adminInfo = new AdminInfoBean();
        // adminInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        adminInfo.setAvatar(primaryPrincipal.getAvatar());
        // adminInfo.setNickName("admin123");
        adminInfo.setNickName(primaryPrincipal.getUsername());
        loginUserData.setAdminInfo(adminInfo);
        // loginUserData.setToken("c4d988f3-e4c5-4e46-b6ce-13b9e008ea20");
        loginUserData.setToken((String) session.getId());
        return BaseRespVo.ok(loginUserData);
    }

    @RequestMapping("info")
    public BaseRespVo info(String token) {


        //开发完shiro之后，再整合
        InfoData infoData = new InfoData();
        MarketAdmin marketAdmin = null;
        try {
            marketAdmin = (MarketAdmin) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        } catch (Exception e) {
            return BaseRespVo.unAuthc();
        }

        // infoData.setName("admin123");
        infoData.setName(marketAdmin.getUsername());

        // 根据primaryPrincipal做查询
        // infoData.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        infoData.setAvatar(marketAdmin.getAvatar());
        Integer[] roles = marketAdmin.getRoleIds();
        // roles.add("超级管理员");
        //infoData.setRoles(new ArrayList<>(Arrays.asList(roles)));
        ArrayList<String> roleNames = new ArrayList<>();
        for (Integer role : roles) {
            String roleName = authService.queryRoleNameByRoleId(role);
            roleNames.add(roleName);
        }
        infoData.setRoles(roleNames);
        ArrayList<String> returnPerms = new ArrayList<>();
        // perms.add("*");
        for (Integer role : roles) {
            if (role == 1) {
                returnPerms.clear();
                returnPerms.add("*");
                break;
            }

            List<String> perms = authService.queryPermissionByRoleId(role);

            for (int i = 0; i < perms.size(); i++) {
                int index = perms.get(i).lastIndexOf(":");
                String operate = perms.get(i).substring(index + 1);
                if ("list".equals(operate) || "read".equals(operate)) {
                    String replaceSymbol = perms.get(i).replaceAll(":", "/");
                    perms.set(i,"GET /" + replaceSymbol);
                } else {
                    String replaceSymbol = perms.get(i).replaceAll(":", "/");
                    perms.set(i,"POST /" + replaceSymbol);
                }
            }


            returnPerms.addAll(perms);
        }


        infoData.setPerms(returnPerms);


        return BaseRespVo.ok(infoData);
    }
}
